#pragma once
#include <torch/torch.h>
#include <LibDL/utils.h>
#include <LibDL/Tensor/Tensor.h>


class Scalar {

	template< class T> static std::string to_string(T val) {
		std::stringstream ss;
		ss << val;
		return ss.str();
	}
public:
	Scalar() = default;
	using core_type = torch::Scalar;
	core_type core;
	ENABLE_CAST;
	std::string to_string() {
		if (core.isComplex()) {
			return to_string(core.toComplexDouble());
		} else if (core.isFloatingPoint()) {
			return to_string(core.toDouble());
		} else {
			return to_string(core.toLong());
		}
	}
	long to_long() {
		return core.toLong();
	}
	double to_double() {
        	return core.toDouble();
	}
#if defined(SWIG)
	%proxycode%{
		
	@Override 
	public String toString() {
		return to_string();
	}

	%}
#endif

#define NISEMONNO(_) \
  _(uint8_t)                                  \
  _(int8_t)                                   \
  _(int16_t)                                 \
  _(int)                                       \
  _(int64_t)                                  \
  _(float)                                   \
  _(double)									\
  _(at::Scalar)
	//using marco from c10 to define constructors.
#define DEFINE_WRAPPER_CTOR(type) Scalar(type const& vv) : core(vv) {}
	NISEMONNO(DEFINE_WRAPPER_CTOR)
#undef DEFINE_WRAPPER_CTOR
#undef NISEMONO
	
};
